package service

import (
	"errors"
	"user/domain/model"
	"user/domain/repository"

	"golang.org/x/crypto/bcrypt"
)

type IUserDataService interface {
	AddUser(*model.User) (int64, error)
	DeleteUser(int64) error
	UpdateUser(user *model.User, isChangePwd bool) error
	FindUserByname(string) (*model.User, error)
	CheckPwd(userName string, pwd string) (isOk bool, err error)
}

// 创建实例
func NewUserDataService(userRepository repository.IUserRepository) IUserDataService {
	return &UserDataService{UserRepository: userRepository}
}

type UserDataService struct {
	UserRepository repository.IUserRepository
}

// 生成加密密码
func GeneratePassword(userPwd string) ([]byte, error) {
	return bcrypt.GenerateFromPassword([]byte(userPwd), bcrypt.DefaultCost)
}

// 验证用户密码
func ValidataPassword(userPwd string, hashed string) (isOk bool, err error) {
	if err = bcrypt.CompareHashAndPassword([]byte(hashed), []byte(userPwd)); err != nil {
		return false, errors.New("密码错误！")
	}
	return true, nil
}

// 插入用户
func (u *UserDataService) AddUser(user *model.User) (userID int64, err error) {
	pwdByte, err := GeneratePassword(user.HashPassword)
	if err != nil {
		return user.ID, nil
	}
	user.HashPassword = string(pwdByte)
	// rabbitmq 发通知
	return u.UserRepository.CreateUser(user)
}

// 删除用户
func (u *UserDataService) DeleteUser(userID int64) error {
	return u.UserRepository.DeleteUser(userID)
}

// 更新用户
func (u *UserDataService) UpdateUser(user *model.User, isChangePwd bool) error {
	// 判断是否更新密码
	if isChangePwd {
		pwdByte, err := GeneratePassword(user.HashPassword)
		if err != nil {
			return err
		}
		user.HashPassword = string(pwdByte)
	}
	// 此处可以记录日志
	return u.UserRepository.UpdateUser(user)
}

// 通过用户名查询用户
func (u *UserDataService) FindUserByname(userName string) (*model.User, error) {
	return u.UserRepository.FindUserByName(userName)
}

// 验证密码
func (u *UserDataService) CheckPwd(userName string, pwd string) (isOk bool, err error) {
	user, err := u.UserRepository.FindUserByName(userName)
	if err != nil {
		return false, err
	}
	return ValidataPassword(pwd, user.HashPassword)
}
